<!DOCTYPE html>
<html lang="en">

<head>
    <title>生死契阔</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,user-scalable=no,minimum-scale=1,maximum-scale=1">
    <style>
        body {
            font-family: Monospace;
            background-color: #f0f0f0;
            margin: 0;
            overflow: hidden
        }
    </style>
</head>

<body>
    <script src="dest/nb.js"></script>
    <script src="dest/Projector.js"></script>
    <script src="dest/CanvasRenderer.js"></script>
    <script src="dest/tween.min.js"></script>
    <script src="dest/Sparks.js"></script>
    <script src="dest/helvetiker_regular.typeface.js"></script>
    <script>
        function init() {
            container = document.createElement("div"), document.body.appendChild(container), (camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1e3)).position.set(0, 150, 800), scene = new THREE.Scene, group = new THREE.Group, scene.add(group);
            var e = "LOVE U",
                t = document.location.hash.substr(1);
            0 !== t.length && (e = t);
            var n = new THREE.TextGeometry(e, {
                size: 80,
                height: 20,
                curveSegments: 2,
                font: "helvetiker"
            });
            n.computeBoundingBox();
            var o = -.5 * (n.boundingBox.max.x - n.boundingBox.min.x),
                i = new THREE.MeshBasicMaterial({
                    color: 16777215 * Math.random(),
                    overdraw: .5
                });
            (text = new THREE.Mesh(n, i)).position.x = o, text.position.y = 100, text.position.z = 0, text.rotation.x = 0, text.rotation.y = 2 * Math.PI, group.add(text), (particleCloud = new THREE.Object3D).y = 800, group.add(particleCloud);
            (heartShape = new THREE.Shape).moveTo(25, 25), heartShape.bezierCurveTo(25, 25, 20, 0, 0, 0), heartShape.bezierCurveTo(-30, 0, -30, 35, -30, 35), heartShape.bezierCurveTo(-30, 55, -10, 77, 25, 95), heartShape.bezierCurveTo(60, 77, 80, 55, 80, 35), heartShape.bezierCurveTo(80, 35, 80, 0, 50, 0), heartShape.bezierCurveTo(35, 0, 25, 25, 25, 25);
            var r = 0,
                a = function(e) {
                    e.globalAlpha = .5;
                    e.scale(.05, -.05), e.beginPath(), e.bezierCurveTo(2.5, 2.5, 2, 0, 0, 0), e.bezierCurveTo(-3, 0, -3, 3.5, -3, 3.5), e.bezierCurveTo(-3, 5.5, -1, 7.7, 2.5, 9.5), e.bezierCurveTo(6, 7.7, 8, 5.5, 8, 3.5), e.bezierCurveTo(8, 3.5, 8, 0, 5, 0), e.bezierCurveTo(3.5, 0, 2.5, 2.5, 2.5, 2.5), e.fill(), e.lineWidth = .5, e.stroke()
                };
            sparksEmitter = new SPARKS.Emitter(new SPARKS.SteadyCounter(160)), emitterpos = new THREE.Vector3, sparksEmitter.addInitializer(new SPARKS.Position(new SPARKS.PointZone(emitterpos))), sparksEmitter.addInitializer(new SPARKS.Lifetime(0, 2)), sparksEmitter.addInitializer(new SPARKS.Target(null, function() {
                var e = new THREE.SpriteCanvasMaterial({
                    program: a
                });
                return e.color.setHSL(r, 1, .75), (r += .001) > 1 && (r -= 1), particle = new THREE.Sprite(e), particle.scale.x = particle.scale.y = 40 * Math.random() + 40, particleCloud.add(particle), particle
            })), sparksEmitter.addInitializer(new SPARKS.Velocity(new SPARKS.PointZone(new THREE.Vector3(0, -50, 10)))), sparksEmitter.addAction(new SPARKS.Age), sparksEmitter.addAction(new SPARKS.Move), sparksEmitter.addAction(new SPARKS.RandomDrift(50, 50, 2e3)), sparksEmitter.addCallback("created", function(e) {
                e.target.position.copy(e.position)
            }), sparksEmitter.addCallback("dead", function(e) {
                e.target.visible = !1, particleCloud.remove(e.target)
            }), sparksEmitter.addCallback("updated", function(e) {
                e.target.position.copy(e.position)
            }), sparksEmitter.start(), (renderer = new THREE.CanvasRenderer).setClearColor(15790320), renderer.setPixelRatio(window.devicePixelRatio), renderer.setSize(window.innerWidth, window.innerHeight), container.appendChild(renderer.domElement), document.addEventListener("mousedown", onDocumentMouseDown, !1), document.addEventListener("touchstart", onDocumentTouchStart, !1), document.addEventListener("touchmove", onDocumentTouchMove, !1), window.addEventListener("resize", onWindowResize, !1)
        }

        function onWindowResize() {
            windowHalfX = window.innerWidth / 2, windowHalfY = window.innerHeight / 2, camera.aspect = window.innerWidth / window.innerHeight, camera.updateProjectionMatrix(), renderer.setSize(window.innerWidth, window.innerHeight)
        }

        function onDocumentMouseDown(e) {
            e.preventDefault(), mouseXOnMouseDown = e.clientX - windowHalfX, targetRotationOnMouseDown = targetRotation, sparksEmitter.isRunning() ? sparksEmitter.stop() : sparksEmitter.start()
        }

        function onDocumentMouseMove(e) {
            mouseX = e.clientX - windowHalfX, targetRotation = targetRotationOnMouseDown + .02 * (mouseX - mouseXOnMouseDown)
        }

        function onDocumentTouchStart(e) {
            1 == e.touches.length && (e.preventDefault(), mouseXOnMouseDown = e.touches[0].pageX - windowHalfX, targetRotationOnMouseDown = targetRotation)
        }

        function onDocumentTouchMove(e) {
            1 == e.touches.length && (e.preventDefault(), mouseX = e.touches[0].pageX - windowHalfX, targetRotation = targetRotationOnMouseDown + .05 * (mouseX - mouseXOnMouseDown))
        }

        function animate() {
            requestAnimationFrame(animate), render()
        }

        function render() {
            (timeOnShapePath += .0337) > 1 && (timeOnShapePath -= 1);
            var e = heartShape.getPointAt(timeOnShapePath);
            emitterpos.x = 5 * e.x - 100, emitterpos.y = 5 * -e.y + 400, group.rotation.y += .05 * (targetRotation - group.rotation.y), renderer.render(scene, camera)
        }
        var container, camera, scene, renderer, group, text, plane, targetRotation = 0,
            targetRotationOnMouseDown = 0,
            mouseX = 0,
            mouseXOnMouseDown = 0,
            windowHalfX = window.innerWidth / 2,
            windowHalfY = window.innerHeight / 2,
            heartShape, particleCloud, sparksEmitter, emitterPos, _rotation = 0,
            timeOnShapePath = 0;
        init(), animate(), document.addEventListener("mousemove", onDocumentMouseMove, !1)
    </script>
    <div style="text-align:center">by ~ meng</div>
</body>

</html>